package com.itbaizhan.clouddemoproduct.config;

import com.itbaizhan.Constant;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.jwt.crypto.sign.MacSigner;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;


@Configuration
@EnableResourceServer  //开启资源器功能
public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {


    /**
     * 方法用于定义资源服务器向远程认证服务器发起验证token的请求
     * @param resources
     * @throws Exception
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        //设置当前资源服务器id
        ResourceServerSecurityConfigurer configurer = resources.resourceId(Constant.product_resource_id);
        configurer.tokenStore(tokenStore()).stateless(true);  // jwt 改造token是无状态设置保存在客户端, session是有状态设置

    }

    /**
     * 此方法用于创建令牌存储对象
     * @return
     */
    private TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    /**
     * 返回令牌转换器
     * @return
     */
    private JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        jwtAccessTokenConverter.setSigningKey(Constant.sign_key);  //签名密钥
        jwtAccessTokenConverter.setVerifier(new MacSigner(Constant.sign_key));
        return jwtAccessTokenConverter;
    }

    /**
     * 对不同特点的接口区别对待, 登录页面就不需要授权就可以访问了, 其他资源接口就需要进行授权认证才能访问
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) //设置session的创建策略
            .and()
            .authorizeRequests()
            .antMatchers("/product/**").authenticated()  //以/product/**开头的接口需要认证授权才能访问
            .anyRequest().permitAll();  //其它请求无需认证
    }
}
